from tkinter import messagebox, ttk
import os
from calc_utils import convert_to_pixels, convert_from_pixels, calculate_optimal_dpi_for_image


class StdSizeMixin:
    def on_standard_size_selected(self, event):
        """处理标准尺寸选择"""
        selected_size = self.standard_size_var.get()

        if selected_size == "自定义":
            # 选择自定义，恢复正常状态
            self.standard_size_applied = False
            self.update_size_state()
            self.restore_original_size()
            return

        # 选择了标准尺寸
        self.standard_size_applied = True

        # 强制启用尺寸修改
        self.size_enabled.set(True)

                # 关闭保持比例相关功能（因为标准尺寸本身就有固定比例）
        self.maintain_ratio.set(False)
        self.batch_maintain_ratio.set(False)
        
        # 强制启用重新采样（用于调整像素以适应新比例）
        self.resampling_enabled.set(True)
        
        # 禁止像素单位选择，如果当前是像素单位，切换到英寸
        if self.unit_var.get() == "pixel":
            self.unit_var.set("inch")

                # 获取标准尺寸（英寸）
        standard_width, standard_height = self.standard_sizes[selected_size]
        
        # 根据原图比例确定横竖向（以第一张图或统一尺寸为参考）
        width_inch, height_inch = self.get_oriented_standard_size(standard_width, standard_height)
        
        # 智能计算DPI，保护图片质量
        suggested_dpi = self.calculate_smart_dpi_for_standard_size(width_inch, height_inch)

                # 根据图片情况决定显示内容
        self.apply_standard_size_display_logic(width_inch, height_inch, suggested_dpi)

        # 更新界面状态
        self.update_size_state()
        self.update_resampling_state()
        self.update_size_display()
        self.update_size_preview()

                # 自动切换到厘米单位并设置正确的标准尺寸数值
        self.unit_var.set("cm")

    def is_standard_size_mode(self):
        """检查是否处于标准尺寸模式"""
        return self.standard_size_applied and self.standard_size_var.get() != "自定义"

    def get_oriented_standard_size(self, standard_width, standard_height):
        """根据原图比例确定标准尺寸的横竖向"""
        # 如果没有选择图片，返回默认方向（竖图方向）
        if not self.selected_files:
            return standard_width, standard_height
        
        # 获取原图尺寸用于判断横竖
        original_width = None
        original_height = None
        
        # 检查图片尺寸是否统一
        _, uniform_width, uniform_height, _, uniform_size = self.check_images_uniformity()
        
        if uniform_size:
            # 图片尺寸统一，使用统一的尺寸
            original_width = uniform_width
            original_height = uniform_height
        else:
            # 图片尺寸不统一，使用第一张图片的尺寸作为参考
            if hasattr(self, 'original_width') and hasattr(self, 'original_height'):
                original_width = self.original_width
                original_height = self.original_height
            elif self.all_images_info:
                original_width = self.all_images_info[0]['width']
                original_height = self.all_images_info[0]['height']
        
        # 如果无法获取原图尺寸，返回默认方向
        if original_width is None or original_height is None:
            return standard_width, standard_height
        
        # 判断原图是横图还是竖图
        is_landscape = original_width > original_height
        
        # 根据原图方向调整标准尺寸
        if is_landscape:
            # 横图：较大值作为宽度
            return max(standard_width, standard_height), min(standard_width, standard_height)
        else:
            # 竖图：较小值作为宽度
            return min(standard_width, standard_height), max(standard_width, standard_height)
    
    def calculate_smart_dpi_for_standard_size(self, target_width_inch, target_height_inch):
        """智能计算DPI以保护图片质量"""
        # 默认DPI
        default_dpi = 300.0

        # 如果没有选择图片，使用默认DPI
        if not self.selected_files or not hasattr(self, 'original_width') or not hasattr(self, 'original_height'):
            return default_dpi

        # 获取原图尺寸
        original_width = self.original_width
        original_height = self.original_height

        # 检查图片尺寸是否统一
        _, uniform_width, uniform_height, _, uniform_size = self.check_images_uniformity()

        if uniform_size:
            # 图片尺寸统一，使用统一的尺寸计算
            original_width = uniform_width
            original_height = uniform_height
        else:
            # 图片尺寸不统一，使用第一张图片的尺寸作为参考
            if self.all_images_info:
                original_width = self.all_images_info[0]['width']
                original_height = self.all_images_info[0]['height']

        # 计算原图的像素总数
        original_pixels = original_width * original_height

        # 设置质量保护因子（保持至少70%的像素数量）
        quality_factor = 0.7
        min_target_pixels = original_pixels * quality_factor

        # 计算目标像素总数
        target_area_sqinch = target_width_inch * target_height_inch

        # 计算需要的DPI以保持质量
        # pixels = dpi² × area_sqinch
        # required_dpi = √(min_target_pixels / target_area_sqinch)
        import math
        required_dpi = math.sqrt(min_target_pixels / target_area_sqinch)

        # 另一种方法：基于宽高分别计算DPI
        required_dpi_width = (original_width * quality_factor ** 0.5) / target_width_inch
        required_dpi_height = (original_height * quality_factor ** 0.5) / target_height_inch
        required_dpi_alt = min(required_dpi_width, required_dpi_height)

        # 取两种方法的较小值（更保守）
        suggested_dpi = max(default_dpi, min(required_dpi, required_dpi_alt))

        # 限制DPI在合理范围内（72-3000）
        suggested_dpi = max(72, min(3000, suggested_dpi))

        # 计算最终像素和质量保持比例
        final_width_px = int(target_width_inch * suggested_dpi)
        final_height_px = int(target_height_inch * suggested_dpi)
        final_pixels = final_width_px * final_height_px
        quality_retention = (final_pixels / original_pixels) * 100

                # 移除弹窗提示，静默处理

        return suggested_dpi

    def apply_standard_size_display_logic(self, width_inch, height_inch, suggested_dpi):
        """根据图片情况应用标准尺寸的显示逻辑"""
        if not self.selected_files:
            # 没有选择图片，显示默认值
            self.dpi_enabled.set(True)
            self.dpi_var.set(str(int(suggested_dpi)))
            width_cm = width_inch * 2.54
            height_cm = height_inch * 2.54
            self.width_var.set(f"{width_cm:.1f}")
            self.height_var.set(f"{height_cm:.1f}")
            # 保持输入框可用状态
            self.width_entry.configure(state="normal")
            self.height_entry.configure(state="normal")
            return
        
        # 检查图片尺寸和方向的统一性
        _, uniform_width, uniform_height, _, uniform_size = self.check_images_uniformity()
        orientation_uniformity = self.check_orientation_uniformity()
        
        if len(self.selected_files) == 1:
            # 单张图片：显示DPI和尺寸，保持输入框可用
            self.dpi_enabled.set(True)
            self.dpi_var.set(str(int(suggested_dpi)))
            width_cm = width_inch * 2.54
            height_cm = height_inch * 2.54
            self.width_var.set(f"{width_cm:.1f}")
            self.height_var.set(f"{height_cm:.1f}")
            self.width_entry.configure(state="normal")
            self.height_entry.configure(state="normal")
            
        elif uniform_size and orientation_uniformity:
            # 批量图片尺寸相同且方向一致：显示DPI和尺寸，保持输入框可用
            self.dpi_enabled.set(True)
            self.dpi_var.set(str(int(suggested_dpi)))
            width_cm = width_inch * 2.54
            height_cm = height_inch * 2.54
            self.width_var.set(f"{width_cm:.1f}")
            self.height_var.set(f"{height_cm:.1f}")
            self.width_entry.configure(state="normal")
            self.height_entry.configure(state="normal")
            
        else:
            # 批量图片尺寸不同或方向混合：完全禁用宽高输入框，清空显示
            self.dpi_enabled.set(False)
            self.dpi_var.set("")
            self.width_var.set("")
            self.height_var.set("")
            # 禁用宽高输入框
            self.width_entry.configure(state="disabled")
            self.height_entry.configure(state="disabled")
    
    def update_standard_size_preview(self):
        """更新标准尺寸模式的预览显示"""
        try:
            selected_size = self.standard_size_var.get()
            if selected_size == "自定义":
                return
            
            # 获取标准尺寸（英寸）
            standard_width, standard_height = self.standard_sizes[selected_size]
            width_inch, height_inch = self.get_oriented_standard_size(standard_width, standard_height)
            
            # 检查图片的统一性
            _, uniform_width, uniform_height, uniform_dpi, uniform_size = self.check_images_uniformity()
            orientation_uniformity = self.check_orientation_uniformity()
            total_files = len(self.selected_files)
            
            # 准备DPI显示文本
            dpi_text = ""
            if self.dpi_enabled.get() and self.dpi_var.get().strip():
                dpi_text = f"DPI: {self.dpi_var.get()}"
            else:
                dpi_text = "DPI: 自动计算（针对每张图片）"
            
            # 准备尺寸显示文本
            size_text = ""
            
            if len(self.selected_files) == 1:
                # 单张图片
                width_cm = width_inch * 2.54
                height_cm = height_inch * 2.54
                suggested_dpi = self.calculate_smart_dpi_for_standard_size(width_inch, height_inch)
                target_pixels_w = int(width_cm / 2.54 * suggested_dpi)
                target_pixels_h = int(height_cm / 2.54 * suggested_dpi)
                size_text = f"{width_cm:.1f}厘米 × {height_cm:.1f}厘米 ({selected_size}) = {target_pixels_w}像素 × {target_pixels_h}像素"
                
            elif uniform_size and orientation_uniformity:
                # 批量图片尺寸相同且方向一致
                width_cm = width_inch * 2.54
                height_cm = height_inch * 2.54
                suggested_dpi = self.calculate_smart_dpi_for_standard_size(width_inch, height_inch)
                target_pixels_w = int(width_cm / 2.54 * suggested_dpi)
                target_pixels_h = int(height_cm / 2.54 * suggested_dpi)
                size_text = f"{width_cm:.1f}厘米 × {height_cm:.1f}厘米 ({selected_size}) = {target_pixels_w}像素 × {target_pixels_h}像素"
                
            else:
                # 批量图片尺寸不同或方向混合
                if not orientation_uniformity:
                    # 横竖图混合的情况
                    landscape_width_inch = max(standard_width, standard_height)
                    landscape_height_inch = min(standard_width, standard_height)
                    portrait_width_inch = min(standard_width, standard_height)
                    portrait_height_inch = max(standard_width, standard_height)
                    
                    landscape_width_cm = landscape_width_inch * 2.54
                    landscape_height_cm = landscape_height_inch * 2.54
                    portrait_width_cm = portrait_width_inch * 2.54
                    portrait_height_cm = portrait_height_inch * 2.54
                    
                    size_text = f"横竖图混合 ({selected_size}):\n"
                    size_text += f"横图: {landscape_width_cm:.1f}厘米 × {landscape_height_cm:.1f}厘米\n"
                    size_text += f"竖图: {portrait_width_cm:.1f}厘米 × {portrait_height_cm:.1f}厘米\n"
                    
                    # 统计横竖图数量
                    landscape_count = 0
                    portrait_count = 0
                    for img_info in self.all_images_info:
                        width = img_info.get('width', 0)
                        height = img_info.get('height', 0)
                        if width > height:
                            landscape_count += 1
                        else:
                            portrait_count += 1
                    
                    size_text += f"横图数量: {landscape_count}, 竖图数量: {portrait_count}"
                else:
                    # 图片方向一致但尺寸不同
                    width_cm = width_inch * 2.54
                    height_cm = height_inch * 2.54
                    size_text = f"批量图片尺寸不同 - 目标尺寸: {width_cm:.1f}厘米 × {height_cm:.1f}厘米 ({selected_size})\n"
                    size_text += "各图片将按标准尺寸进行智能缩放，DPI自动优化"
            
            # 更新显示
            if self.mode_var.get() == "folder":
                self.preview_label.configure(
                    text=f"{dpi_text}\n{size_text}\n处理文件数: {total_files}"
                )
            else:
                self.preview_label.configure(text=f"{dpi_text}\n{size_text}")
                
        except Exception as e:
            self.preview_label.configure(text=f"标准尺寸预览错误: {str(e)}")
    
    def check_orientation_uniformity(self):
        """检查所有图片的方向是否一致（都是横图或都是竖图）"""
        if not self.all_images_info:
            return True
        
        orientations = []
        for img_info in self.all_images_info:
            width = img_info.get('width', 0)
            height = img_info.get('height', 0)
            is_landscape = width > height
            orientations.append(is_landscape)
        
        # 检查是否所有图片方向都一致
        return len(set(orientations)) == 1
    
    def get_orientation_info(self):
        """获取横竖图的提示信息"""
        selected_size = self.standard_size_var.get()
        if selected_size == "自定义" or selected_size not in self.standard_sizes:
            return ""
        
        base_width, base_height = self.standard_sizes[selected_size]
        larger = max(base_width, base_height)
        smaller = min(base_width, base_height)
        
        return f"横图：{larger}×{smaller}英寸，竖图：{smaller}×{larger}英寸"
    
    def on_unit_change_for_standard_size(self, *args):
        """当用户在标准尺寸模式下切换单位时，自动转换数值"""
        if not self.is_standard_size_mode():
            return

        selected_size = self.standard_size_var.get()
        if selected_size == "自定义":
            return

        # 检查图片统一性，决定是否显示数值
        _, uniform_width, uniform_height, _, uniform_size = self.check_images_uniformity()
        orientation_uniformity = self.check_orientation_uniformity()
        
        # 如果批量图片尺寸不统一或方向混合，不设置数值
        if len(self.selected_files) > 1 and (not uniform_size or not orientation_uniformity):
            self.width_var.set("")
            self.height_var.set("")
            return

        # 获取标准尺寸（英寸）
        base_width, base_height = self.standard_sizes[selected_size]
        width_inch, height_inch = self.get_oriented_standard_size(base_width, base_height)

        # 获取当前DPI设置
        current_dpi = 300.0
        if self.dpi_enabled.get() and self.dpi_var.get().strip():
            try:
                current_dpi = float(self.dpi_var.get())
            except ValueError:
                current_dpi = 300.0

        # 根据新选择的单位设置尺寸值
        current_unit = self.unit_var.get()
        if current_unit == "inch":
            self.width_var.set(f"{width_inch:.1f}")
            self.height_var.set(f"{height_inch:.1f}")
        elif current_unit == "cm":
            # 将英寸转换为厘米 (1英寸 = 2.54厘米)
            width_cm = width_inch * 2.54
            height_cm = height_inch * 2.54
            self.width_var.set(f"{width_cm:.1f}")
            self.height_var.set(f"{height_cm:.1f}")
        else:  # pixel
            # 使用当前DPI计算像素
            width_px = int(width_inch * current_dpi)
            height_px = int(height_inch * current_dpi)
            self.width_var.set(str(width_px))
            self.height_var.set(str(height_px))


    pass
